package com.kh.pajx.sop.util.sop;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.Encoder;
import org.owasp.esapi.codecs.Codec;
import org.owasp.esapi.codecs.OracleCodec;
import org.owasp.esapi.reference.DefaultEncoder;

import com.kh.pajx.sop.util.web.Constants;

/**
 * 该类主要校验属性值，避免不合法参数进入
 * @author:	azzcsimp
 * @Createdate:	2014年12月31日 上午11:15:00
 */
public class PropertyValidate {
	
	private static final Codec oracleCodec = new OracleCodec();
	
	/**
	 * 校验字符串只允许中文、字母、数字组成
	 * @param value
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月5日 上午11:26:59
	 */
	public static boolean validateSafeString(String value){
		Pattern pt = Pattern.compile("^[A-Za-z0-9\u4e00-\u9fa5（）]+$");
		return pt.matcher(value).matches();
	}
	
	public static boolean validateSafeString(String value, int maxLength){
		if(validateStrByLength(value,maxLength)){
			return validateSafeString(value);
		}
		return false;
	}
	
	public static boolean validateSafeString(String value, int maxLength, boolean allowNull){
		if(StringUtils.isBlank(value)){
			if(!allowNull){
				return false;
			}
			return true;
		}
		return validateSafeString(value, maxLength);
	}
	
	public static boolean validateSafeLetterAndNumString(String value){
		Pattern pt = Pattern.compile("^[A-Za-z0-9]+$");
		return pt.matcher(value).matches();
	}
	
	public static boolean validateSafeLetterAndNumString(String value, int maxLength){
		if(validateStrByLength(value,maxLength)){
			return validateSafeLetterAndNumString(value);
		}
		return false;
	}
	
	public static boolean validateSafeLetterAndNumString(String value, int maxLength, boolean allowNull){
		if(StringUtils.isBlank(value)){
			if(!allowNull){
				return false;
			}
			return true;
		}
		return validateSafeLetterAndNumString(value, maxLength);
	}
	
	
	/**
	 * 校验32位uuid
	 * @param uuid 需要校验的uuid
	 * @return   boolean 符合规范 true 不符合false
	 * @author:	azzcsimp
	 * @Createdate:	2014年12月31日 上午11:57:41
	 */
	public static boolean validateUUID(String uuid){
		Pattern ptUUID = Pattern.compile("[a-zA-Z0-9]{32,32}");
		return ptUUID.matcher(uuid).matches();
	}
	
	/**
	 * 校验32位uuid
	 * @param uuid 需要校验的uuid
	 * @param allowNull true允许为空 false 不允许为空
	 * @return boolean 符合规范 true 不符合false
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月5日 上午12:38:41
	 */
	public static boolean validateUUID(String uuid, boolean allowNull){
		if(StringUtils.isBlank(uuid)){
			if(!allowNull){
				return false;
			}
			return true;
		}else{
			return validateUUID(uuid);
		}
	}
	
	/**
	 * 校验纯数字编码
	 * @param areaCode 编码
	 * @param limitLength 编码限制长度
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月2日 下午4:13:52
	 */
	public static boolean validateNumberCode(String code, int limitLength){
		Pattern ptNo = Pattern.compile("[0-9]{"+limitLength+"}");
		return ptNo.matcher(code).matches();
	}
	
	public static boolean validateNumberCode(String code, int limitLength, boolean allowNull){
		if(StringUtils.isEmpty(code)){
			if(!allowNull){
				return false;
			}
			return true;
		}else{
			return validateNumberCode(code, limitLength);
		}
	}
	
	public static boolean validateNumberCode(Integer code, int limitLength, boolean allowNull){
		if(code!=null){
			return validateNumberCode(code+"", limitLength);
		}else{
			if(!allowNull){
				return false;
			}
			return true;
		}
	}

	/**
	 * 验证字符串长度是否符合要求，一个汉字等于三个字符(UTF-8,GBK编码是2个字符)
	 * @param value 要验证的字符串
	 * @param limitLength 验证长度
	 * @return	boolean 符合长度true 超出范围false
	 * @author:	azzcsimp
	 * @Createdate:	2014年12月31日 上午11:29:08
	 */
	public static boolean validateStrByLength(String value, int limitLength) {
		int temp_int = 0;
		byte[] b = value.getBytes();

		for (int i = 0; i < b.length; i++) {
			if (b[i] >= 0) {
				temp_int = temp_int + 1;
			} else {
				temp_int = temp_int + 2;
				i++;
			}
		}

		if (temp_int > limitLength) {
			return false;
		} else {
			return true;
		}
	}
	

	/**
	 * 校验手机号 1开头的11位数字
	 * @param phone 需要验证的字符串
	 * @return   boolean 符合格式true 不符合false
	 * @author:	azzcsimp
	 * @Createdate:	2014年12月31日 下午1:29:18
	 */
	public static boolean validatePhone(String phone){
		Pattern ptPhone = Pattern.compile("^1\\d{10}$");
		return ptPhone.matcher(phone).matches();
	}
	
	public static boolean validatePhone(String phone, boolean allowNull){
		if(StringUtils.isEmpty(phone)){
			if(!allowNull){
				return false;
			}
			return true;
		}else{
			return validatePhone(phone);
		}
	}
	
	/**
	 * 校验6位数字验证码
	 * @param code 需要验证的字符串
	 * @return   boolean 符合格式true 不符合false
	 * @author:	azzcsimp
	 * @Createdate:	2014年12月31日 下午1:31:41
	 */
	public static boolean validateCode(String code){
		Pattern ptCode = Pattern.compile("^\\d{6}$");
		return ptCode.matcher(code).matches();
	}
	
	/**
	 * 校验订单编号19位数字组成
	 * @param orderNo 需要验证的字符串
	 * @return   boolean 符合格式true 不符合false
	 * @author:	azzcsimp
	 * @Createdate:	2014年12月31日 下午4:12:49
	 */
	public static boolean validateOrderNo(String orderNo){
		Pattern ptOrderNo = Pattern.compile("[0-9]{19}");
		return ptOrderNo.matcher(orderNo).matches();
	}
	
	/**
	 * 校验学校编号 5位数字组成
	 * @param sclNo
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月2日 下午4:04:35
	 */
	public static boolean validateSclNo(String sclNo){
		Pattern ptsclNo = Pattern.compile("[0-9]{5}");
		return ptsclNo.matcher(sclNo).matches();
	}
	
	
	/**
	 * 校验市区编码 4位数字组成
	 * @param areaCode
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月2日 下午4:06:32
	 */
	public static boolean validateAreaCode(String areaCode){
		Pattern ptAreaCode = Pattern.compile("[0-9]{4}");
		return ptAreaCode.matcher(areaCode).matches();
	}
	
	/**
	 * 校验县区编码6位数字组成
	 * @param CountyCode 
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月2日 下午4:07:53
	 */
	public static boolean validateCountyCode(String CountyCode){
		Pattern ptCountyCode = Pattern.compile("[0-9]{6}");
		return ptCountyCode.matcher(CountyCode).matches();
	}
	
	
	
	/**
	 * 校验IP
	 * @param value
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月4日 下午8:14:13
	 */
	public static boolean validateIP(String value){
		Pattern ptIP = Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
		return ptIP.matcher(value).matches();
	}
	
	/**
	 * 校验电子邮件
	 * @param value
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月4日 下午8:14:20
	 */
	public static boolean validateEmail(String value){
		Pattern ptEmail = Pattern.compile("^[A-Za-z0-9._%'-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$");
		return ptEmail.matcher(value).matches();
	}
	
	/**
	 * 验证首位不为0且最大长度为maxLength的数字
	 * @param value
	 * @param maxLength
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月4日 下午8:26:32
	 */
	public static boolean validateNumber(String value,int maxLength){
		Pattern ptNumber = Pattern.compile("^[1-9]\\d{0,"+(maxLength-1)+"}$");
		return ptNumber.matcher(value).matches();
	}
	
	
	/**
	 * 防止SQL注入
	 * @param value
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月4日 下午7:50:26
	 */
	public static String encodeForSql(String value){
		return ESAPI.encoder().encodeForSQL(oracleCodec, value);
	}
	
	/**
	 * 参数规范操作(转码)
	 * @param value
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月4日 下午8:40:36
	 */
	public static String canonicalize(String value){
		if (value == null || value.equals("")) {
			return value;
		}
		Encoder encoder = new DefaultEncoder(Constants.codecList);
		String clean = encoder.canonicalize(value);
		return clean;
	}
	
	/**
	 * 防止SQL注入
	 * @param value
	 * @param canonicalize
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月4日 下午8:42:19
	 */
	public static String encodeForSql(String value,boolean canonicalize){
		if(canonicalize){
			return ESAPI.encoder().encodeForSQL(oracleCodec, canonicalize(value));
		}else{
			return encodeForSql(value);
		}
	}
	
	/**
	 * 快译报表表单验证
	 * @param name
	 * @param value
	 * @return   
	 * @author:	azzcsimp
	 * @Createdate:	2015年1月4日 下午9:27:28
	 */
	public static String validateKYReportInput(String name,String value){
		if(kyReportParams.contains(name)){
			if(name.equals("end_date")){
				if(validateStrByLength(value, 10)){
					return encodeForSql(value);
				}
			}
			if(name.equals("areaCode")){
				if(validateAreaCode(value)){
					return value;
				}
			}
			
			if(name.equals("cityCode")){
				if(validateCountyCode(value)){
					return value;
				}
			}
			
			if(name.equals("report_flag")){
				if(validateNumberCode(value, 1)){
					return value;
				}
			}
		}
		return "";
	}
	
	public static List<String> kyReportParams;
	
	static{
		kyReportParams = new ArrayList<String>();
		kyReportParams.add("end_date");
		kyReportParams.add("areaCode");
		kyReportParams.add("report_flag");
		kyReportParams.add("cityCode");
	}
	
	public static void main(String[] args) {
		
	/*	System.out.println("卧槽".length());
		System.out.println(validateStrByLength("卧槽", 5));
		System.out.println(validateStrByLength("abcd", 5));
		System.out.println(StringUtils.isNotEmpty(null));
		System.out.println(ESAPI.encoder().encodeForSQL(new OracleCodec(), "Jeff'' or ''1''=''1"));
		System.out.println(ESAPI.encoder().encodeForSQL(new OracleCodec(), "WHERE 1 = 1"));
		System.out.println(ESAPI.encoder().encodeForHTML("<script>alert('我了个打草')</script>"));
		System.out.println(validateNumberCode("2",1));
		System.out.println();
		
		Encoder encoder = new DefaultEncoder(Constants.codecList);
		String clean = encoder.canonicalize("model.sclName='\"--></style></scRipt><scRipt>netsparker(0x000467)</scRipt>&sclNumber=3&areaCode=4110&countyCode=MIDDX&deptCode=1003&saleUserId=4028851d4aa433e6014aa444e29d0000&balanceTypeFlag=3&checkStatusFlag=3");
		System.out.println(clean);
		System.out.println(validateIP("123.123.123.123"));
		System.out.println(validateNumber("111",2));
		Encoder encoder = new DefaultEncoder(Constants.codecList);
		String clean = encoder.canonicalize("%27");
		System.out.println(clean);
		System.out.println(encodeForSql(clean));
		System.out.println(encodeForSql("%27",true));
		codecList.add("HTMLEntityCodec");  // HTMLEntity
    	codecList.add("XMLEntityCodec");   // XMLEntity
    	codecList.add("PercentCodec");     // precent
    	codecList.add("JavaScriptCodec");  // javascript
    	codecList.add("VBScriptCodec");    // VBScript
    	codecList.add("CSSCodec");         // CSS
    	codecList.add("WindowsCodec");     // windows
    	codecList.add("OracleCodec");      // oracle
		*/
		Encoder encoder = new DefaultEncoder(Constants.codecList);
		String xxoo = "model.sclName='\"--></style></scRipt><scRipt>netsparker(0x000467)</scRipt>&sclNumber=3&areaCode=4110&countyCode=MIDDX&deptCode=1003&saleUserId=4028851d4aa433e6014aa444e29d0000&balanceTypeFlag=3&checkStatusFlag=3";
		String clean = encoder.canonicalize(xxoo);
		System.out.println(clean);
		
		/*List list = new ArrayList();
		list.add("HTMLEntityCodec");
		Encoder encoder2 = new DefaultEncoder(list);
		System.out.println(encoder2.canonicalize(xxoo));
		
		list.add("XMLEntityCodec");   // XMLEntity
		Encoder encoder3 = new DefaultEncoder(list);
		System.out.println(encoder3.canonicalize(xxoo));
		
		
		list.add("PercentCodec");   // XMLEntity
		Encoder encoder4 = new DefaultEncoder(list);
		System.out.println(encoder4.canonicalize(xxoo));
		
		list.add("JavaScriptCodec");   // XMLEntity
		Encoder encoder5 = new DefaultEncoder(list);
		System.out.println("5:"+encoder5.canonicalize(xxoo));
		
		//list.add("VBScriptCodec");   // XMLEntity
		Encoder encoder6 = new DefaultEncoder(list);
		System.out.println("6:"+encoder6.canonicalize(xxoo));
		
		list.add("CSSCodec");   // XMLEntity
		Encoder encoder7 = new DefaultEncoder(list);
		System.out.println(encoder7.canonicalize(xxoo));
		
		list.add("WindowsCodec");   // XMLEntity
		Encoder encoder8 = new DefaultEncoder(list);
		System.out.println(encoder8.canonicalize(xxoo));
		
		list.add("OracleCodec");   // XMLEntity
		Encoder encoder9 = new DefaultEncoder(list);
		System.out.println(encoder9.canonicalize(xxoo));*/
		
		System.out.println(encodeForSql("\""));
		
		System.out.println(ESAPI.encoder().encodeForHTML("\"卧槽"));
		
		System.out.println(validateSafeString("asdfsadfasf（）"));
	}
}
